package com.zwps.biz.domain.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;

import cn.hutool.core.util.StrUtil;

import com.zwps.biz.domain.converter.RegionConverter;
import com.zwps.biz.domain.service.RegionService;
import com.zwps.biz.api.model.dto.region.SelectRegionDTO;
import com.zwps.biz.api.model.vo.region.RegionTreeVO;
import com.zwps.biz.api.model.vo.region.RegionVO;
import com.zwps.biz.dal.db.dao.RegionDAO;
import com.zwps.biz.dal.db.object.RegionDO;
import com.zwps.common.core.exception.UserActionException;
import com.zwps.common.core.service.CommonService;
import com.zwps.common.tool.tree.TreeTool;

import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.function.Function;

@Service
@AllArgsConstructor
public class RegionServiceImpl implements RegionService, CommonService {


    private RegionDAO regionDAO;

    @Override
    public RegionVO getRegion(String regionCode) {
        RegionDO regionDO = regionDAO
                .selectOne(Wrappers.lambdaQuery(RegionDO.class).eq(RegionDO::getRegionCode, regionCode));
        if (regionDO == null) {
            throw new UserActionException("行政区划编码不存在：" + regionCode);
        }
        return RegionConverter.INSTANCE.toRegionVO(regionDO);
    }

    @Override
    public List<RegionTreeVO> findTree(String parentRegionCode) {
        LambdaQueryWrapper<RegionDO> wrapper = Wrappers.lambdaQuery(RegionDO.class);
        if (StrUtil.isNotEmpty(parentRegionCode)) {
            RegionDO regionDO = regionDAO.selectById(parentRegionCode);
            if (regionDO == null) {
                throw new UserActionException("查询指定的行政区不存在");
            }
            wrapper.eq(RegionDO::getParentRegionCode, parentRegionCode);
        }
        List<RegionDO> deptList = regionDAO.selectList(wrapper);
        if (deptList.isEmpty()) {
            return CollUtil.newArrayList();
        }
        Function<RegionDO, RegionTreeVO> treeInstance = (a) -> {
            return RegionConverter.INSTANCE.toRegionTreeVO(a);
        };

        return TreeTool.build(deptList, treeInstance, (a) -> a.getId(), (a) -> a.getParentRegionCode(),
                (a) -> a.getRegionName(), (a) -> Integer.valueOf(a.getRegionCode()));
    }

    @Override
    public List<RegionVO> searchRegion(SelectRegionDTO dto) {

        LambdaQueryWrapper<RegionDO> regionQuery = Wrappers.lambdaQuery(RegionDO.class);
        regionQuery.like(StrUtil.isNotEmpty(dto.getRegionName()), RegionDO::getRegionName, dto.getRegionName());
        regionQuery.in(CollectionUtil.isNotEmpty(dto.getRegionCodes()), RegionDO::getRegionCode, dto.getRegionCodes());
        regionQuery.eq(StrUtil.isNotEmpty(dto.getParentRegionCode()), RegionDO::getParentRegionCode, dto.getParentRegionCode());
        regionQuery.in(CollectionUtil.isNotEmpty(dto.getIds()), RegionDO::getId, dto.getIds());

        List<RegionDO> regionDOList = regionDAO.selectList(regionQuery);
        if (CollectionUtils.isEmpty(regionDOList)) {
            return Lists.newArrayList();
        }
        return RegionConverter.INSTANCE.toRegionVOList(regionDOList);
    }


}
